/*-------------------------------------------------------------------------
 *
 * optimizer.h
 *	  Postgres规划器的外部API。
 *
 * 本头文件旨在定义核心规划器向非规划器模块公开的所有内容。
 *
 * 请注意，在 src/backend/optimizer/ 之外的文件被视为规划器模块，因为它们与规划器操作密切相关，无法以其他方式处理。FDW 规划代码就是一个例子。然而，大多数情况下，核心规划器外的代码不需要包含任何优化器/头文件，除了这个。
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/optimizer/optimizer.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef OPTIMIZER_H
#define OPTIMIZER_H

#include "nodes/parsenodes.h"

/*
 * 我们不想在这里包含 nodes/pathnodes.h，因为非规划器
 * 代码通常应将 PlannerInfo 视为不透明的 typedef。
 * 但我们希望这样的代码使用该 typedef 名称，因此在这里或在 pathnodes.h 中定义
 * 该 typedef，以先读取的为准。
 */
#ifndef HAVE_PLANNERINFO_TYPEDEF
typedef struct PlannerInfo PlannerInfo;
#define HAVE_PLANNERINFO_TYPEDEF 1
#endif

/* IndexOptInfo 和 SpecialJoinInfo 也同样如此。 */
#ifndef HAVE_INDEXOPTINFO_TYPEDEF
typedef struct IndexOptInfo IndexOptInfo;
#define HAVE_INDEXOPTINFO_TYPEDEF 1
#endif
#ifndef HAVE_SPECIALJOININFO_TYPEDEF
typedef struct SpecialJoinInfo SpecialJoinInfo;
#define HAVE_SPECIALJOININFO_TYPEDEF 1
#endif

/* 在这里包含 plannodes.h、params.h 或 htup.h 似乎也最为合适 */
struct PlannedStmt;
struct ParamListInfoData;
struct HeapTupleData;


/* 在 path/clausesel.c 中: */

extern Selectivity clause_selectivity(PlannerInfo *root,
									  Node *clause,
									  int varRelid,
									  JoinType jointype,
									  SpecialJoinInfo *sjinfo);
extern Selectivity clause_selectivity_ext(PlannerInfo *root,
										  Node *clause,
										  int varRelid,
										  JoinType jointype,
										  SpecialJoinInfo *sjinfo,
										  bool use_extended_stats);
extern Selectivity clauselist_selectivity(PlannerInfo *root,
										  List *clauses,
										  int varRelid,
										  JoinType jointype,
										  SpecialJoinInfo *sjinfo);
extern Selectivity clauselist_selectivity_ext(PlannerInfo *root,
											  List *clauses,
											  int varRelid,
											  JoinType jointype,
											  SpecialJoinInfo *sjinfo,
											  bool use_extended_stats);

/* 在 path/costsize.c 中: */

/* 广泛使用的成本参数 */
extern PGDLLIMPORT double seq_page_cost;
extern PGDLLIMPORT double random_page_cost;
extern PGDLLIMPORT double cpu_tuple_cost;
extern PGDLLIMPORT double cpu_index_tuple_cost;
extern PGDLLIMPORT double cpu_operator_cost;
extern PGDLLIMPORT double parallel_tuple_cost;
extern PGDLLIMPORT double parallel_setup_cost;
extern PGDLLIMPORT double recursive_worktable_factor;
extern PGDLLIMPORT int effective_cache_size;

extern double clamp_row_est(double nrows);
extern long clamp_cardinality_to_long(Cardinality x);

/* 在 path/indxpath.c 中: */

extern bool is_pseudo_constant_for_index(PlannerInfo *root, Node *expr,
										 IndexOptInfo *index);

/* 在 plan/planner.c 中: */

/* force_parallel_mode 的可能值 */
typedef enum
{
	FORCE_PARALLEL_OFF,
	FORCE_PARALLEL_ON,
	FORCE_PARALLEL_REGRESS
}			ForceParallelMode;

/* GUC 参数 */
extern PGDLLIMPORT int force_parallel_mode;
extern PGDLLIMPORT bool parallel_leader_participation;

extern struct PlannedStmt *planner(Query *parse, const char *query_string,
								   int cursorOptions,
								   struct ParamListInfoData *boundParams);

extern Expr *expression_planner(Expr *expr);
extern Expr *expression_planner_with_deps(Expr *expr,
										  List **relationOids,
										  List **invalItems);

extern bool plan_cluster_use_sort(Oid tableOid, Oid indexOid);
extern int	plan_create_index_workers(Oid tableOid, Oid indexOid);

/* 在 plan/setrefs.c 中: */

extern void extract_query_dependencies(Node *query,
									   List **relationOids,
									   List **invalItems,
									   bool *hasRowSecurity);

/* 在 prep/prepqual.c 中: */

extern Node *negate_clause(Node *node);
extern Expr *canonicalize_qual(Expr *qual, bool is_check);

/* 在 util/clauses.c 中: */

extern bool contain_mutable_functions(Node *clause);
extern bool contain_mutable_functions_after_planning(Expr *expr);
extern bool contain_volatile_functions(Node *clause);
extern bool contain_volatile_functions_after_planning(Expr *expr);
extern bool contain_volatile_functions_not_nextval(Node *clause);

extern Node *eval_const_expressions(PlannerInfo *root, Node *node);

extern void convert_saop_to_hashed_saop(Node *node);

extern Node *estimate_expression_value(PlannerInfo *root, Node *node);

extern Expr *evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod,
						   Oid result_collation);

extern List *expand_function_arguments(List *args, bool include_out_arguments,
									   Oid result_type,
									   struct HeapTupleData *func_tuple);

/* 在 util/predtest.c 中: */

extern bool predicate_implied_by(List *predicate_list, List *clause_list,
								 bool weak);
extern bool predicate_refuted_by(List *predicate_list, List *clause_list,
								 bool weak);

/* 在 util/tlist.c 中： */

extern int	count_nonjunk_tlist_entries(List *tlist);
extern TargetEntry *get_sortgroupref_tle(Index sortref,
										 List *targetList);
extern TargetEntry *get_sortgroupclause_tle(SortGroupClause *sgClause,
											List *targetList);
extern Node *get_sortgroupclause_expr(SortGroupClause *sgClause,
									  List *targetList);
extern List *get_sortgrouplist_exprs(List *sgClauses,
									 List *targetList);
extern SortGroupClause *get_sortgroupref_clause(Index sortref,
												List *clauses);
extern SortGroupClause *get_sortgroupref_clause_noerr(Index sortref,
													  List *clauses);

/* 在 util/var.c 中: */

/* 可以与 pull_var_clause() 的 flags 参数进行 OR 运算的位 */
#define PVC_INCLUDE_AGGREGATES	0x0001	/* 在输出列表中包含 Aggrefs */
#define PVC_RECURSE_AGGREGATES	0x0002	/* 递归到 Aggref 参数中 */
#define PVC_INCLUDE_WINDOWFUNCS 0x0004	/* 在输出列表中包含 WindowFuncs */
#define PVC_RECURSE_WINDOWFUNCS 0x0008	/* 递归到 WindowFunc 参数中 */
#define PVC_INCLUDE_PLACEHOLDERS	0x0010	/* 在输出列表中包含 PlaceHolderVars */
#define PVC_RECURSE_PLACEHOLDERS	0x0020	/* 递归到 PlaceHolderVar 参数中 */

extern Bitmapset *pull_varnos(PlannerInfo *root, Node *node);
extern Bitmapset *pull_varnos_of_level(PlannerInfo *root, Node *node, int levelsup);
extern void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos);
extern List *pull_vars_of_level(Node *node, int levelsup);
extern bool contain_var_clause(Node *node);
extern bool contain_vars_of_level(Node *node, int levelsup);
extern int	locate_var_of_level(Node *node, int levelsup);
extern List *pull_var_clause(Node *node, int flags);
extern Node *flatten_join_alias_vars(Query *query, Node *node);

#endif							/* OPTIMIZER_H */
